package com.bfsoft.springbootinit.util;


import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;

/**
 * @ClassName: DateUtil
 * @Description: TODO
 * @Author: huc
 * @Date: 2021/6/29 10:52
 * @Version: v1.0
 */
public class DateUtil {
    public static final String MONTH_PATTERN = "yyyy-MM";
    public static final String DEFAULT_PATTERN = "yyyyMMdd";
    public static final String FULL_PATTERN = "yyyyMMddHHmmss";
    public static final String FULL_STANDARD_PATTERN = "yyyyMMdd HH:mm:ss";
    public static final String CHINESE_PATTERN = "yyyy-MM-dd";
    public static final String FULL_CHINESE_PATTERN = "yyyy-MM-dd HH:mm:ss";
    public static final String TIMESTAMP = "yyyyMMddHHmmssSSSSSSSSS";

    public DateUtil() {
    }

    public static int dateAdd(String interval, int number, Date date) {
        long d = date2MysqlDate(date);
        return dateAdd(interval, number, d);
    }

    public static Date getDateByAdd(String interval, int number, Date date) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        if ("d".equals(interval)) {
            now.set(5, now.get(5) + number);
        } else if ("m".equals(interval)) {
            now.set(2, now.get(2) + number);
        } else if ("y".equals(interval)) {
            now.set(1, now.get(1) + number);
        } else if ("h".equals(interval)) {
            now.set(10, now.get(10) + number);
        } else if ("n".equals(interval)) {
            now.set(12, now.get(12) + number);
        } else if ("s".equals(interval)) {
            now.set(13, now.get(13) + number);
        }

        return now.getTime();
    }

    public static int dateAdd(String interval, int number, long timestamp) {
        Long l = Long.valueOf("10000000000");
        if (timestamp >= l) {
            timestamp /= 1000L;
        }

        long myTime = 0L;
        if ("d".equals(interval)) {
            myTime = timestamp + (long)(86400 * number);
        } else if ("w".equals(interval)) {
            myTime = timestamp + (long)(86400 * number * 7);
        } else if ("m".equals(interval)) {
            myTime = timestamp + (long)(86400 * number * 30);
        } else if ("y".equals(interval)) {
            myTime = timestamp + (long)(86400 * number * 365);
        } else if ("h".equals(interval)) {
            myTime = timestamp + (long)(3600 * number);
        } else if ("n".equals(interval)) {
            myTime = timestamp + (long)(60 * number);
        } else if ("s".equals(interval)) {
            myTime = timestamp + (long)number;
        }

        return (int)myTime;
    }

    public static int dateDiff(String interval, long date1, long date2) {
        Long l = Long.valueOf("10000000000");
        if (date1 >= l) {
            date1 /= 1000L;
        }

        if (date2 >= l) {
            date2 /= 1000L;
        }

        long d = 0L;
        if ("d".equals(interval)) {
            d = (date1 - date2) / 86400L;
        } else if ("w".equals(interval)) {
            d = (date1 - date2) / 604800L;
        } else if ("m".equals(interval)) {
            d = (date1 - date2) / 2592000L;
        } else if ("y".equals(interval)) {
            d = (date1 - date2) / 31536000L;
        } else if ("h".equals(interval)) {
            d = (date1 - date2) / 3600L;
        } else if ("n".equals(interval)) {
            d = (date1 - date2) / 60L;
        } else if ("s".equals(interval)) {
            d = date1 - date2;
        }

        return (int)Math.abs(d);
    }

    public static Date getDate(String name, String df, Date defaultValue) {
        if (name == null) {
            return defaultValue;
        } else {
            SimpleDateFormat formatter = new SimpleDateFormat(df);

            try {
                return formatter.parse(name);
            } catch (ParseException var5) {
                return defaultValue;
            }
        }
    }

    public static Date getDateDf(String name, String df) {
        return getDate(name, df, (Date)null);
    }

    public static Date getDate(String name) {
        return getDate(name, (Date)null);
    }

    public static Date getDateTime(String name) {
        return getDateTime(name, (Date)null);
    }

    public static Date getDate(String name, Date defaultValue) {
        return getDate(name, "yyyy-MM-dd", defaultValue);
    }

    public static Date getDateTime(String name, Date defaultValue) {
        return getDate(name, "yyyy-MM-dd HH:mm:ss", defaultValue);
    }

    public static int parseStr(String str) {
        return parseStr(str, "yyyy-MM-dd HH:mm:ss");
    }

    public static Date parseStrDate(String str, String format) {
        if (StringUtils.isEmpty(str)) {
            return null;
        } else {
            SimpleDateFormat sd = new SimpleDateFormat(format);
            ParsePosition pos = new ParsePosition(0);
            return sd.parse(str, pos);
        }
    }

    public static int parseStr(String str, String format) {
        Date d1 = parseStrDate(str, format);
        return d1 == null ? 0 : (int)(d1.getTime() / 1000L);
    }

    public static int getDatebyUnix(long l) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        return parseStr(formatter.format(l) + " 00:00:00");
    }

    public static Date mysqlDate2Date(int seconds) {
        long l = (long)seconds * 1000L;
        Date date = new Date(l);
        return date;
    }

    public static long date2MysqlDate(Date date) {
        return date.getTime() / 1000L;
    }

    public static int date2MysqlDateInt(Date date) {
        long l = date2MysqlDate(date);
        return Integer.parseInt(String.valueOf(l));
    }

    public static int getBetweenTime(Calendar earlyDate, Calendar lateDate, int returnTimeFormat) {
        earlyDate = (Calendar)earlyDate.clone();
        lateDate = (Calendar)lateDate.clone();

        int time;
        for(time = 0; earlyDate.before(lateDate); ++time) {
            earlyDate.add(returnTimeFormat, 1);
        }

        return time;
    }

    public static int getBetweenTime(Date earlyDate, Date lateDate, int returnTimeFormat) {
        Calendar cnow = Calendar.getInstance();
        cnow.setTime(earlyDate);
        Calendar clast = Calendar.getInstance();
        clast.setTime(lateDate);
        return getBetweenTime(cnow, clast, returnTimeFormat);
    }

    public static int getBetweenDays(Date begin, Date last) {
        return getBetweenTime((Date)begin, (Date)last, 5);
    }

    public static int getBetweenHours(Date begin, Date last) {
        return getBetweenTime((Date)begin, (Date)last, 11);
    }

    public static int getBetweenMins(Date begin, Date last) {
        return getBetweenTime((Date)begin, (Date)last, 12);
    }

    public static int getBetweenMonths(Date begin, Date last) {
        return getBetweenTime((Date)begin, (Date)last, 2);
    }

    public static int getBetweenYears(Date begin, Date last) {
        return getBetweenTime((Date)begin, (Date)last, 1);
    }

    public static int getBetweenDays(int last) {
        Calendar cnow = Calendar.getInstance();
        Calendar clast = Calendar.getInstance();
        clast.setTime(mysqlDate2Date(last));
        int between = getBetweenTime((Calendar)clast, (Calendar)cnow, 5);
        return between;
    }

    public static String dateFormate(Date date, String formate, boolean useUSA) {
        if (date != null) {
            SimpleDateFormat sdf = null;
            if (useUSA) {
                sdf = new SimpleDateFormat(formate, Locale.US);
            } else {
                sdf = new SimpleDateFormat(formate);
            }

            return sdf.format(date);
        } else {
            return null;
        }
    }

    public static String dateFormate(Date date, String formate) {
        return dateFormate(date, formate, false);
    }

    public static String dateFormateHuman(int seconds) {
        Date date = mysqlDate2Date(seconds);
        return dateFormateHuman(date);
    }

    public static String dateFormateHuman(Date date) {
        Calendar cnow = Calendar.getInstance();
        Calendar clast = Calendar.getInstance();
        cnow.setTime(new Date());
        clast.setTime(date);
        String format = "";
        if (cnow.get(1) == clast.get(1) && cnow.get(2) == clast.get(2) && cnow.get(5) == clast.get(5)) {
            format = "H:mm";
        } else if (cnow.get(1) == clast.get(1)) {
            format = "M月d日";
        } else {
            format = "yyyy年M月d日";
        }

        return dateFormate(date, format);
    }

    public static String getTimeBetweenHuman(int seconds) {
        return getTimeBetweenHuman(mysqlDate2Date(seconds));
    }

    public static String getTimeBetweenHuman(Date date) {
        Calendar cnow = Calendar.getInstance();
        Calendar clast = Calendar.getInstance();
        cnow.setTime(new Date());
        clast.setTime(date);
        String re = "";
//        int b = false;
        int b;
        if (cnow.get(1) == clast.get(1) && cnow.get(2) == clast.get(2) && cnow.get(5) == clast.get(5) && cnow.get(11) == clast.get(11)) {
            b = getBetweenMins(clast.getTime(), cnow.getTime());
            re = "分钟";
        } else if (cnow.get(1) == clast.get(1) && cnow.get(2) == clast.get(2) && cnow.get(5) == clast.get(5)) {
            b = getBetweenHours(clast.getTime(), cnow.getTime());
            re = "小时";
        } else {
            b = getBetweenDays(clast.getTime(), cnow.getTime());
            re = "天";
        }

        return b + re;
    }

    public static String dateFormate(int seconds, String formate) {
        Date date = mysqlDate2Date(seconds);
        return dateFormate(date, formate);
    }

    public static Date clearHMS(Date date) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.set(11, 0);
        now.set(12, 0);
        now.set(13, 0);
        now.set(14, 0);
        return now.getTime();
    }

    public static Date getPrevDate(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar now = Calendar.getInstance();
            now.setTime(date);
            now.set(5, now.get(5) - 1);
            return now.getTime();
        }
    }

    public static Date getNextDate(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar now = Calendar.getInstance();
            now.setTime(date);
            now.set(5, now.get(5) + 1);
            return now.getTime();
        }
    }

    public static Date getNextMonth(Date date) {
        if (date == null) {
            return null;
        } else {
            Calendar now = Calendar.getInstance();
            now.setTime(date);
            now.set(2, now.get(2) + 1);
            return now.getTime();
        }
    }

//    public static String getStrDateBefor(int createdDate) {
//        if (createdDate <= 0) {
//            return "9999";
//        } else {
//            Calendar createDate = Calendar.getInstance();
//            Calendar nowDate = Calendar.getInstance();
//            createDate.setTime(mysqlDate2Date(createdDate));
//            int datesBefor = getBetweenTime((Calendar)createDate, (Calendar)nowDate, 5);
//            String sDatesBefor = StringUtils.getIndexString(datesBefor, 4);
//            return sDatesBefor;
//        }
//    }

    public static Date createDate(long date) {
        return new Date(date);
    }

    public static Date createDate(String date) {
        try {
            return createDate(Long.parseLong(date));
        } catch (Exception var2) {
            return new Date();
        }
    }

    public static Date getDateByDayOfWeek(Date date, Integer dayOfWeek) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        Integer currentDayOfWeek = cal.get(7) - 1;
        if (Objects.equals(dayOfWeek, currentDayOfWeek)) {
            return cal.getTime();
        } else {
            if (dayOfWeek == 0) {
                dayOfWeek = 7;
            }

            cal.set(5, cal.get(5) + (dayOfWeek - currentDayOfWeek));
            return cal.getTime();
        }
    }
}
